﻿using System;
using System.Collections.Generic;
using RiskMan.DataClass.Models.Level;
using RiskMan.Config;
using TheControllerRisk.Settings;
using RiskMan.DataClass.Models.NotBasModels;
using System.Windows.Media;

namespace RiskMan.Views.Level
{
    class LevelLogik
    {
        private DataClass.Data data;
        private MainWindow mainWindow;
        private Level level;
        double TTP_Last;
        string Classcode;
        private MediaPlayer player = new MediaPlayer();
        private static int tmp = 1;
        int accuraccy;

        public LevelLogik()
        { }

        public LevelLogik(MainWindow mainWindow, Level level)
        {
            this.mainWindow = mainWindow;
            this.data = mainWindow.DataProvider;
            this.level = level;
        }

        public void Start(LevelItem lvItem)
        {
            //цена последней сделки
            TTP_Last = mainWindow.DataProvider.GetLastPrice(lvItem.Instrument);
            Classcode = mainWindow.DataProvider.GetClasscode(lvItem.Instrument);
            accuraccy = mainWindow.DataProvider.GetAccuraccy(lvItem.Instrument);
            lvItem.LastPrice = TTP_Last;



            // время работы
            if (new WorkingTimeClass(lvItem.Account).IsWork() == true )
            {
                if ((lvItem.TradeList == null || lvItem.TradeList.Count == 0) && lvItem.NumberOfAttempt > lvItem.CurNumberOfAttempt)
                {
                    if (lvItem.TypeLevel == cfg.HorizontalLevel)
                        OpenOrderNew(lvItem);

                    if (lvItem.TypeLevel == cfg.HorizontalLevelFalse)
                        OpenOrderNewHorizontalLevelFalse(lvItem);

                    if (lvItem.TypeLevel == cfg.DoubleLevel)
                        OpenOrderDoubleLevel(lvItem);
                }
                if ((lvItem.TradeList == null || lvItem.TradeList.Count == 0))
                    lvItem.CurPosition = 0;

                ////если в трейдлисте уже есть заявки
                if (lvItem.TradeList.Count > 0)
                {
                    GetStatusAndBalance(lvItem);
                    KillOpenOrderforCondidtion(lvItem);

                    //GetStatusAndBalance(lvItem);
                    lvItem.CurPosition = 0;
                    foreach (var item in lvItem.TradeList)
                    {
                        if (item.OpenBalance > 0)
                        {
                            if (lvItem.Operation == cfg.Buy)
                                lvItem.CurPosition = lvItem.CurPosition + item.OpenBalance;
                            else
                                lvItem.CurPosition = lvItem.CurPosition - item.OpenBalance;

                            if (lvItem.SoundOpenPoz == false)
                            {
                                if (!String.IsNullOrEmpty(Properties.Settings.Default.SoundOpenPoz))
                                    PlaySound(Properties.Settings.Default.SoundOpenPoz);
                                lvItem.SoundOpenPoz = true;
                            }
                        }
                    }


                    //Выставление стопй-заявок на закрытие позиций
                    if (lvItem.TradeList.Count > 0)
                    {
                        if (lvItem.CurPosition != 0 && (lvItem.TradeList[0].StopLimitCloseStatusOrder == null || (lvItem.TradeList[0].StopLimitCloseStatusOrder == cfg.Cancel && lvItem.TradeList[0].CloseStatusOrder == cfg.Cancel)))
                            CloseStopOrder(lvItem);
                        if (lvItem.TradeList[0].StopLimitCloseStatusOrder != null)
                        {
                            if (Properties.Settings.Default.adapter == cfg.adapterQuik)
                                GetStatusAndBalanceStopLimit(lvItem);
                        }

                    }

                }

                //обнуление активации перестановки в безубыток при нулевой позиции
                if (lvItem.CurPosition == 0)
                    lvItem.BreakevenActive = false;

                lvItem.PrevLastPrice = TTP_Last;
            }
        }

        /// <summary>
        /// Проигрывание музыки при совершении действия
        /// </summary>
        /// <param name="PathSound"></param>
        private void PlaySound(string PathSound)
        {
            player.Stop();
            player.Open(new Uri(PathSound, UriKind.Relative));
            player.Play();
        }

        /// <summary>
        /// Выставляем заявку на отрткрытие позиции при горизонтальном уровне
        /// </summary>
        /// <param name="ldItem"></param>
        private void OpenOrderNew(LevelItem Item)
        {

            if (Item.TradeList == null)
                Item.TradeList = new System.Collections.ObjectModel.ObservableCollection<TradesOpen>();

            if (Item.Operation == cfg.Buy && Item.PrevLastPrice != 0)
                if (Item.PrevLastPrice <= Item.trendItem.HorizontalLevel + Item.Excess && TTP_Last > Item.trendItem.HorizontalLevel + Item.Excess)
                {
                    AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel + Item.Excess + Item.SettingOrderOpenClose.OtstupForOpenOrder), Item.Operation == "Купля" ? 'B' : 'S');
                }

            if (Item.Operation == cfg.Sell && Item.PrevLastPrice != 0)
                if (Item.PrevLastPrice >= Item.trendItem.HorizontalLevel - Item.Excess && TTP_Last < Item.trendItem.HorizontalLevel + Item.Excess)
                {
                    AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel - Item.Excess - Item.SettingOrderOpenClose.OtstupForOpenOrder), Item.Operation == "Купля" ? 'B' : 'S');
                }
        }

        /// <summary>
        /// Выставляем заявку на отрткрытие позиции при горизонтальном уровне с ложным пробоем
        /// </summary>
        /// <param name="ldItem"></param>
        private void OpenOrderNewHorizontalLevelFalse(LevelItem Item)
        {
            if (Item.TradeList == null)
                Item.TradeList = new System.Collections.ObjectModel.ObservableCollection<TradesOpen>();

            if (Item.Operation == cfg.Buy && Item.PrevLastPrice != 0)
            {
                if (Item.PrevLastPrice >= Item.trendItem.HorizontalLevel && TTP_Last < Item.trendItem.HorizontalLevel)
                {
                    Item.trendItem.FlagProboiLevel = true;
                    Item.trendItem.FlagTimePeroid = DateTime.Now;
                }
                //проверка времени находждения и пройденного расстояния
                if (Item.trendItem.FlagProboiLevel == true)
                {
                    if (Item.trendItem.HorizontalLevel - Item.trendItem.MinProkol >= TTP_Last)
                    {
                        Item.trendItem.FlagDiapazonLevel = true;
                        Item.Comment = "Цена пришла в зону минильного прокола. Робот ждет возвращения цены к роботу";
                    }
                    if (Item.trendItem.FlagTimePeroid.TimeOfDay + TimeConvertor(Item.trendItem.TimeFalseProboi) <= DateTime.Now.TimeOfDay)
                    {
                        Item.trendItem.FlagDiapazonLevel = false;
                        Item.trendItem.FlagProboiLevel = false;
                        Item.Comment = "Нахождение за уровнем больше положенного времени. Работа по уровню прекращена";
                    }
                    if (Item.trendItem.HorizontalLevel - Item.trendItem.MaxProkol > TTP_Last)
                    {
                        Item.trendItem.FlagDiapazonLevel = false;
                        Item.trendItem.FlagProboiLevel = false;
                        Item.Comment = "Цена ушла дальше максимального прокола. Работа по уровню прекращена";
                    }

                    //Вход в позицию
                    if (Item.trendItem.FlagDiapazonLevel = true && Item.PrevLastPrice < Item.trendItem.HorizontalLevel && TTP_Last >= Item.trendItem.HorizontalLevel)
                    {
                        Item.Comment = "Выставлена заявка на открытие позиции";
                        AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel + Item.SettingOrderOpenClose.OtstupForOpenOrder), Item.Operation == "Купля" ? 'B' : 'S');
                    }
                }
            }

            if (Item.Operation == cfg.Sell && Item.PrevLastPrice != 0)
            {
                if (Item.PrevLastPrice <= Item.trendItem.HorizontalLevel && TTP_Last > Item.trendItem.HorizontalLevel)
                {
                    Item.trendItem.FlagProboiLevel = true;
                    Item.trendItem.FlagTimePeroid = DateTime.Now;
                }
                //проверка времени находждения и пройденного расстояния
                if (Item.trendItem.FlagProboiLevel == true)
                {
                    if (Item.trendItem.HorizontalLevel + Item.trendItem.MinProkol <= TTP_Last)
                    {
                        Item.trendItem.FlagDiapazonLevel = true;
                        Item.Comment = "Цена пришла в зону минильного прокола. Робот ждет возвращения цены к роботу";
                    }
                    if (Item.trendItem.FlagTimePeroid.TimeOfDay + TimeConvertor(Item.trendItem.TimeFalseProboi) <= DateTime.Now.TimeOfDay)
                    {
                        Item.trendItem.FlagDiapazonLevel = false;
                        Item.trendItem.FlagProboiLevel = false;
                        Item.Comment = "Нахождение за уровнем больше положенного времени. Работа по уровню прекращена";
                    }
                    if (Item.trendItem.HorizontalLevel + Item.trendItem.MaxProkol < TTP_Last)
                    {
                        Item.trendItem.FlagDiapazonLevel = false;
                        Item.trendItem.FlagProboiLevel = false;
                        Item.Comment = "Цена ушла дальше максимального прокола. Работа по уровню прекращена";
                    }

                    if (Item.trendItem.FlagDiapazonLevel = true && Item.PrevLastPrice > Item.trendItem.HorizontalLevel && TTP_Last <= Item.trendItem.HorizontalLevel)
                    {
                        Item.Comment = "Выставлена заявка на открытие позиции";
                        AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel - Item.SettingOrderOpenClose.OtstupForOpenOrder), Item.Operation == "Купля" ? 'B' : 'S');
                    }
                }
            }
        }

        /// <summary>
        /// Обработки логики двойного уровня
        /// </summary>
        /// <param name="item"></param>
        private void OpenOrderDoubleLevel(LevelItem Item)
        {
            if (Item.TradeList == null)
                Item.TradeList = new System.Collections.ObjectModel.ObservableCollection<TradesOpen>();

            if (Item.PrevLastPrice != 0)
                if (Item.PrevLastPrice <= Item.trendItem.UpLevel + Item.Excess && TTP_Last > Item.trendItem.UpLevel)
                {
                    AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel + Item.SettingOrderOpenClose.OtstupForOpenOrder), 'B');
                }

            if (Item.PrevLastPrice != 0)
                if (Item.PrevLastPrice >= Item.trendItem.DownLevel - Item.Excess && TTP_Last < Item.trendItem.DownLevel)
                {
                    AddOrderOpenTotradeList(Item, Classcode, Math.Round(Item.trendItem.HorizontalLevel - Item.SettingOrderOpenClose.OtstupForOpenOrder), 'S');
                }

        }

        /// <summary>
        /// Выставление стоп-заявок на закрытие позиции
        /// </summary>
        /// <param name="lvItem"></param>
        private void CloseStopOrder(LevelItem lvItem)
        {
            //находимся в лонге
            double PriceFilled = 0;
            double PriceProfit = 0;
            double StopPrice = GetStopPrice(lvItem, ref PriceFilled, ref PriceProfit);

            if (lvItem.SettingOrderOpenClose.TypeStop == cfg.LinkedOrder)
            {
                if (Properties.Settings.Default.adapter == cfg.adapterQuik)
                    lvItem.TradeList[0].StopLimitCloseID = mainWindow.Terminals.SendLinkedStop(lvItem.Operation == "Купля" ? 'S' : 'B', lvItem.Account, Classcode, lvItem.Instrument, lvItem.ClientCode,
                        Math.Abs(lvItem.CurPosition), StopPrice, PriceFilled, PriceProfit);


                if (lvItem.Operation == "Купля")
                {
                    lvItem.TradeList[0].StopLimitCloseOperation = cfg.Sell;
                    lvItem.TradeList[0].StopLimitClosePrice = StopPrice;
                }
                else
                {
                    lvItem.TradeList[0].StopLimitCloseOperation = cfg.Buy;
                    lvItem.TradeList[0].StopLimitClosePrice = StopPrice;
                }

                lvItem.TradeList[0].StopLimitCloseQuantity = lvItem.CurPosition;
                lvItem.TradeList[0].StopLimitCloseStatusOrder = cfg.Unknown;
                lvItem.TradeList[0].StopLimitCloseDate = DateTime.Now;

            }
        }

        /// <summary>
        /// Проверяем нужно ли переносить стоп в безубыток
        /// </summary>
        /// <param name="lvitem"></param>
        /// <returns></returns>
        private void RemoveStopBreakeven(LevelItem lvitem, double price)
        {

            if (lvitem.Breakeven != 0 && !lvitem.BreakevenActive)
            {
                if (lvitem.CurPosition > 0)
                    if (TTP_Last >= price + lvitem.Breakeven+lvitem.BreakevenOtstup)
                        lvitem.BreakevenActive = true;
                if (lvitem.CurPosition < 0)
                    if (TTP_Last <= price - lvitem.Breakeven -lvitem.BreakevenOtstup)
                        lvitem.BreakevenActive = true;
            }


        }

        /// <summary>
        /// Рассчитваем цену активации в зависимости от выбарнного типа расчета
        /// </summary>
        /// <param name="lvitem"></param>
        /// <returns></returns>
        private double GetStopPrice(LevelItem lvitem, ref double priceFilled, ref double priceProfit)
        {
            double result = 0;

            if (lvitem.SettingOrderOpenClose.TypePricing == cfg.TypeCloseOrderAuto)
            {
                if (lvitem.CurPosition > 0)
                {
                    if (lvitem.TypeLevel == cfg.HorizontalLevel)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.HorizontalLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.HorizontalLevel + lvitem.Excess - lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.HorizontalLevel + lvitem.Excess + lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.HorizontalLevel;
                            priceProfit = lvitem.trendItem.HorizontalLevel + lvitem.Excess + lvitem.SettingOrderOpenClose.Profit;
                        }
                    }
                    if (lvitem.TypeLevel == cfg.HorizontalLevelFalse)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.HorizontalLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.HorizontalLevel - lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.HorizontalLevel + lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.HorizontalLevel;
                            priceProfit = lvitem.trendItem.HorizontalLevel + lvitem.SettingOrderOpenClose.Profit;
                        }
                    }

                    if (lvitem.TypeLevel == cfg.DoubleLevel)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.UpLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.UpLevel - lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.UpLevel + lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.UpLevel;
                            priceProfit = lvitem.trendItem.UpLevel + lvitem.SettingOrderOpenClose.Profit;
                        }
                    }

                    priceFilled = result - lvitem.SettingOrderOpenClose.StopLimitSpred;
                }
                if (lvitem.CurPosition < 0)
                {
                    if (lvitem.TypeLevel == cfg.HorizontalLevel)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.HorizontalLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.HorizontalLevel - lvitem.Excess + lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.HorizontalLevel - lvitem.Excess - lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.HorizontalLevel - lvitem.Excess;
                            priceProfit = lvitem.trendItem.HorizontalLevel - lvitem.Excess - lvitem.SettingOrderOpenClose.Profit;
                        }
                    }
                    if (lvitem.TypeLevel == cfg.HorizontalLevelFalse)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.HorizontalLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.HorizontalLevel + lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.HorizontalLevel - lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.HorizontalLevel;
                            priceProfit = lvitem.trendItem.HorizontalLevel - lvitem.SettingOrderOpenClose.Profit;
                        }
                    }
                    if (lvitem.TypeLevel == cfg.DoubleLevel)
                    {
                        RemoveStopBreakeven(lvitem, lvitem.trendItem.DownLevel);

                        if (!lvitem.BreakevenActive)
                        {
                            result = lvitem.trendItem.DownLevel + lvitem.SettingOrderOpenClose.StopLimitOtstup;
                            priceProfit = lvitem.trendItem.DownLevel - lvitem.SettingOrderOpenClose.Profit;
                        }
                        else
                        {
                            result = lvitem.trendItem.DownLevel;
                            priceProfit = lvitem.trendItem.DownLevel - lvitem.SettingOrderOpenClose.Profit;
                        }
                    }

                    priceFilled = result + lvitem.SettingOrderOpenClose.StopLimitSpred;
                }
            }
            else
            {
                result = lvitem.SettingOrderOpenClose.StopLimitOtstup;
                priceFilled = lvitem.SettingOrderOpenClose.StopLimitSpred;
                priceProfit = lvitem.SettingOrderOpenClose.Profit;
            }

            return result;
        }

        /// <summary>
        /// Отправка транзакций в зависимости от терминала
        /// </summary>
        /// <param name="ldItem"></param>
        /// <param name="oper"></param>
        /// <param name="PriceOpen"></param>
        /// <returns></returns>
        public long sendLimitOrderToTerminal(LevelItem ldItem, char oper, double PriceOpen)
        {
            long ID = 0;

            if (Properties.Settings.Default.adapter == cfg.adapterQuik)
                ID = mainWindow.Terminals.SendOrder(ldItem.Account, ldItem.ClientCode, oper,
                        PriceOpen, ldItem.Quantity, ldItem.Instrument, Classcode);
           
            return ID;
        }

        /// <summary>
        /// выставляем заявкку на откртыие позиции и записываем в лист
        /// </summary>
        /// <param name="ldItem"></param>
        /// <param name="Classcode"></param>
        /// <param name="PriceOpen"></param>
        /// <param name="oper"></param>
        private void AddOrderOpenTotradeList(LevelItem ldItem, string Classcode, double PriceOpen, char oper)
        {
            TradesOpen tradesOpen = new TradesOpen();
            tradesOpen.OpenDate = DateTime.Now;
            if (ldItem.SettingOrderOpenClose.TypeOrderOpen == cfg.openOrderLimit)
                tradesOpen.OpenID = sendLimitOrderToTerminal(ldItem, oper, PriceOpen);
            else
            {
                if (Classcode != "SPBFUT")
                    tradesOpen.OpenID = mainWindow.Terminals.SendMMMarketID(ldItem.Account, ldItem.ClientCode, oper,
                    ldItem.Quantity, ldItem.Instrument, Classcode, "");
                else
                    tradesOpen.OpenID = mainWindow.Terminals.SendOrder(ldItem.Account, ldItem.ClientCode, oper,
                        data.GetMaxMinPrice(ldItem.Instrument, 'B'),
                        ldItem.Quantity, ldItem.Instrument, Classcode);
            }
            if (oper == 'B')
            {
                tradesOpen.OpenOperation = "Купля";
                tradesOpen.OpenPriceOrder = PriceOpen - ldItem.SettingOrderOpenClose.OtstupForOpenOrder;
            }
            else
            {
                tradesOpen.OpenOperation = "Продажа";
                tradesOpen.OpenPriceOrder = PriceOpen + ldItem.SettingOrderOpenClose.OtstupForOpenOrder;
            }

            tradesOpen.OpenQuantity = ldItem.Quantity;
            tradesOpen.OpenStatusOrder = cfg.Unknown;
            ldItem.TradeList.Add(tradesOpen);
            ldItem.CurNumberOfAttempt += 1;

            if (!String.IsNullOrEmpty(Properties.Settings.Default.SoundOrder))
                PlaySound(Properties.Settings.Default.SoundOrder);
            ldItem.SoundOrder = true;
            ldItem.SoundClosePoz = false;
            ldItem.SoundOpenPoz = false;

        }

        /// <summary>
        /// блок проверки заявок на изменение статуса и баланса
        /// </summary>
        /// <param name="ld"></param>
        public void GetStatusAndBalance(LevelItem ld)
        {
            try
            {
                var orderMassiv = data.GetOrderListAll(ld.Account, ld.ClientCode);

                for (int i = 0; i < ld.TradeList.Count; i++)
                {
                    if (ld.TradeList.Count == 0)
                        break;

                    #region Проверка объема
                    foreach (var item2 in orderMassiv)
                    {
                        //проверка статусов на изменение заявок на открытие пока балансе не равен выставленному числу
                        if (item2.TID == ld.TradeList[i].OpenID && ld.TradeList[i].OpenBalance != ld.TradeList[i].OpenQuantity)
                        {
                            ld.TradeList[i].OpenNumberOrder = item2.Number;
                            ld.TradeList[i].OpenStatusOrder = item2.Status;
                            if (ld.TradeList[i].OpenQuantity == item2.Count)
                                ld.TradeList[i].OpenBalance = item2.Count - item2.OstCount;
                            else
                            {
                                //если заявка снята либо в конце сеесии либо врунчую и надо выставляться на меньший объем
                                if (ld.TradeList[i].OpenQuantity > ld.TradeList[i].OpenBalance + item2.OstCount)
                                    ld.TradeList[i].OpenBalance = ld.TradeList[i].OpenQuantity - item2.OstCount;
                                if (ld.TradeList[i].OpenQuantity == ld.TradeList[i].OpenBalance + item2.OstCount && item2.OstCount == 0)
                                    ld.TradeList[i].OpenBalance = ld.TradeList[i].OpenQuantity;
                            }
                        }

                        //проверка статусов на изменение заявок на закрытие позиции пока балансе не равен выставленному числу
                        if (ld.TradeList[i].OpenBalance == ld.TradeList[i].OpenQuantity)
                            if (item2.TID == ld.TradeList[i].CloseID && ld.TradeList[i].CloseBalance != ld.TradeList[i].CloseQuantity)
                            {
                                ld.TradeList[i].CloseNumberOrder = item2.Number;
                                ld.TradeList[i].CloseStatusOrder = item2.Status;
                                if (ld.TradeList[i].CloseQuantity == item2.Count)
                                    ld.TradeList[i].CloseBalance = item2.Count - item2.OstCount;
                                else
                                {
                                    //если заявка снята либо в конце сеесии либо врунчую и надо выставляться на меньший объем
                                    if (ld.TradeList[i].CloseQuantity > ld.TradeList[i].CloseBalance + item2.OstCount)
                                        ld.TradeList[i].CloseBalance = ld.TradeList[i].CloseQuantity - item2.OstCount;
                                    if (ld.TradeList[i].CloseQuantity == ld.TradeList[i].CloseBalance + item2.OstCount && item2.OstCount == 0)
                                        ld.TradeList[i].CloseBalance = ld.TradeList[i].CloseQuantity;
                                }
                            }
                    }
                    #endregion


                    //если в течении 10 секунд заявка не появилась в системе удалить ее, или ее сняли в ручном формате и не было исполнения, или удаляетс из списка если заявка не определена и уже ее смотрят в другом дне. На закрытие позиции
                    if ((ld.TradeList[i].CloseDate.TimeOfDay + new TimeSpan(0, 0, 20) <= DateTime.Now.TimeOfDay && ld.TradeList[i].CloseStatusOrder == cfg.Unknown)
                        || (ld.TradeList[i].CloseDate.Date != DateTime.Now.Date && (ld.TradeList[i].CloseStatusOrder == cfg.Unknown)))
                    {
                        ld.TradeList.Remove(ld.TradeList[i]);
                        if (i > 0)
                            i--;
                        if (i == 0)
                            break;
                    }

                    //если при переходе в другой день, заявки на закрытие остались активными, то сбросить их в статус null
                    if (ld.TradeList[i].CloseDate.Date != DateTime.Now.Date && ld.TradeList[i].CloseStatusOrder == cfg.Active)
                        ld.TradeList[i].CloseStatusOrder = null;

                    //если в течении 10 секунд заявка не появилась в системе удалить ее, или ее сняли в ручном формате и не было исполнения, или удаляетс из списка если заявка не определена и уже ее смотрят в другом дне
                    if ((ld.TradeList[i].OpenDate.TimeOfDay + new TimeSpan(0, 0, 20) <= DateTime.Now.TimeOfDay && ld.TradeList[i].OpenStatusOrder == cfg.Unknown)
                        || (ld.TradeList[i].OpenStatusOrder == cfg.Cancel && ld.TradeList[i].OpenBalance == 0)
                        || (ld.TradeList[i].OpenDate.Date != DateTime.Now.Date && (ld.TradeList[i].OpenStatusOrder == cfg.Unknown || ld.TradeList[i].OpenStatusOrder == cfg.Active))
                        )
                    {
                        if (ld.TradeList[i].OpenBalance == 0)
                        {
                            ld.TradeList.Remove(ld.TradeList[i]);
                            if (i > 0)
                                i--;
                            if (i == 0)
                                break;
                        }
                        else
                        {
                            ld.TradeList[i].OpenStatusOrder = null;
                        }
                    }

                    if (ld.TradeList[i].OpenStatusOrder == cfg.Cancel && ld.TradeList[i].OpenBalance != 0)
                    {
                        ld.TradeList[i].OpenStatusOrder = null;
                    }

                    //Заявка на открытие и закрытие исполнились полностью
                    if (ld.TradeList[i].CloseStatusOrder == cfg.Performed && ld.TradeList[i].OpenQuantity == ld.TradeList[i].OpenBalance &&
                        ld.TradeList[i].CloseStatusOrder == cfg.Performed && ld.TradeList[i].CloseQuantity == ld.TradeList[i].CloseBalance)
                    {
                        ld.TradeList.Remove(ld.TradeList[i]);
                        if (i > 0)
                            i--;
                        if (i == 0)
                            break;
                    }


                }
            }
            catch
            { }
        }

        /// <summary>
        /// блок проверки стоп-заявок статуса и баланса
        /// </summary>
        /// <param name="ld"></param>
        public void GetStatusAndBalanceStopLimit(LevelItem ld)
        {
            try
            {
                var orderMassiv = data.GetOrderListAll(ld.Account, ld.ClientCode);
                var StopLimitMassiv = data.GetStopOrderList(ld.Account, ld.ClientCode);


                #region Проверка по цене для стопа часть 1 из 3

                double PriceFilled = 0;
                double PriceProfit = 0;
                double StopPrice = GetStopPrice(ld, ref PriceFilled, ref PriceProfit);

                #endregion



                //Проверка исполнения заявки типа связанная заявка
                if (ld.SettingOrderOpenClose.TypeStop == cfg.LinkedOrder)
                    for (int i = 0; i < ld.TradeList.Count; i++)
                    {
                        if (ld.TradeList.Count == 0)
                            break;

                        #region стоп лимит
                        foreach (var item2 in StopLimitMassiv)
                        {
                            //проверка статусов на изменение заявок на открытие пока балансе не равен выставленному числу
                            if (item2.TID == ld.TradeList[i].StopLimitCloseID && ld.TradeList[i].StopLimitCloseStatusOrder != cfg.Cancel && ld.TradeList[i].StopLimitCloseStatusOrder != cfg.Performed)
                            {
                                ld.TradeList[i].StopLimitCloseNumberOrder = item2.Number;
                                ld.TradeList[i].StopLimitCloseStatusOrder = item2.Status;
                            }
                            if (item2.TID == ld.TradeList[i].StopLimitCloseID)
                            {
                                if (ld.TradeList[i].StopLimitCloseStatusOrder != cfg.Unknown || String.IsNullOrEmpty(ld.TradeList[i].StopLimitCloseResult))
                                    ld.TradeList[i].StopLimitCloseResult = item2.Result;
                                //если стоп-заявка отвергнута системой выставляем еще раз
                                if (ld.TradeList[i].StopLimitCloseResult == cfg.RemoveFormTs)
                                    ld.TradeList[i].StopLimitCloseStatusOrder = null;
                                //определяем номер заявки выставленной в систему при активации стоп-заявки
                                if (ld.TradeList[i].StopLimitCloseResult == cfg.AddToTs)
                                    ld.TradeList[i].StopLimitCloseNumberLinkidOrder = item2.NumberOrder;
                            }

                            #region Проверка по цене для стопа часть 2 из 3

                            if (item2.TID == ld.TradeList[i].StopLimitCloseID && ld.TradeList[i].StopLimitCloseStatusOrder == cfg.Active)
                            {
                                //Проверка по цене активации
                                if (ld.TimeKillStopOrder.TimeOfDay + new TimeSpan(0, 0, 10) <= DateTime.Now.TimeOfDay)
                                {
                                    if (item2.StopPrice != StopPrice)
                                    {
                                        mainWindow.Terminals.CancelStopOrder(item2.Number, ld.Instrument, Classcode, ld.Account, ld.ClientCode);
                                        ld.TimeKillStopOrder = DateTime.Now;
                                    }
                                }
                            }


                            #endregion

                        }

                        //по прошествии 10 или уже другая дата секунд стоп-заявку можно снять снова, если не получилось с первого раза
                        if ((ld.TimeKillStopOrder.TimeOfDay + new TimeSpan(0, 0, 10) <= DateTime.Now.TimeOfDay || ld.TimeKillStopOrder.Date != DateTime.Now.Date) && ld.TimeKillStopOrder != new DateTime())
                        {
                            ld.TimeKillStopOrder = new DateTime();
                        }

                        //если в течении 10 секунд стоп-заявка не появилась в системе удалить ее, или ее сняли в ручном формате и не было исполнения, или удаляетс из списка если заявка не определена и уже ее смотрят в другом дне. На закрытие позиции
                        if ((ld.TradeList[i].StopLimitCloseDate.TimeOfDay + new TimeSpan(0, 0, 10) <= DateTime.Now.TimeOfDay && ld.TradeList[i].StopLimitCloseStatusOrder == cfg.Unknown)
                            || (ld.TradeList[i].StopLimitCloseDate.Date != DateTime.Now.Date && (ld.TradeList[i].StopLimitCloseStatusOrder == cfg.Unknown)))
                        {
                            ld.TradeList[i].StopLimitCloseStatusOrder = null;
                        }
                        #endregion


                        //провереям заявки на выставление
                        if (ld.TradeList[i].StopLimitCloseStatusOrder != null && ld.TradeList[i].StopLimitCloseStatusOrder != cfg.Unknown)
                        {
                            foreach (var item2 in orderMassiv)
                            {
                                //проверка статусов на изменение заявок на закрытие позиции
                                if (ld.TradeList[i].StopLimitCloseID == item2.TID && ld.TradeList[i].CloseStatusOrder == null)
                                {
                                    ld.TradeList[i].CloseStatusOrder = item2.Status;
                                    ld.TradeList[i].CloseNumberOrder = item2.Number;
                                    ld.TradeList[i].CloseID = item2.TID;
                                }

                                if (ld.TradeList[i].CloseStatusOrder != null && ld.TradeList[i].CloseID == item2.TID && ld.TradeList[i].StopLimitCloseNumberLinkidOrder == 0)
                                    ld.TradeList[i].CloseStatusOrder = item2.Status;

                                //удаляем трейдлист, если происходит исполнение заявки на профит
                                if (ld.TradeList[i].CloseStatusOrder == cfg.Performed)
                                {
                                    ld.TradeList.Remove(ld.TradeList[i]);
                                    if (i > 0)
                                        i--;
                                    if (i == 0)
                                        break;
                                }

                                if (ld.TradeList[i].StopLimitCloseResult == cfg.AddToTs)
                                {
                                    if (ld.TradeList[i].StopLimitCloseNumberLinkidOrder == item2.Number && ld.TradeList[i].OrderFromStopLimitCloseStatusOrder == null)
                                    {
                                        ld.TradeList[i].OrderFromStopLimitCloseStatusOrder = item2.Status;
                                        ld.TradeList[i].OrderFromStopLimitCloseNumberOrder = item2.Number;
                                        ld.TradeList[i].OrderFromStopLimitCloseID = item2.TID;
                                    }

                                    if (ld.TradeList[i].OrderFromStopLimitCloseStatusOrder != null && ld.TradeList[i].OrderFromStopLimitCloseID == item2.TID && ld.TradeList[i].StopLimitCloseNumberLinkidOrder == item2.Number)
                                        ld.TradeList[i].OrderFromStopLimitCloseStatusOrder = item2.Status;

                                    //если заявка снята (возможно ручками) исполнена в полном объеме
                                    if (ld.TradeList[i].OrderFromStopLimitCloseStatusOrder == cfg.Performed)
                                    {
                                        ld.TradeList.Remove(ld.TradeList[i]);
                                        if (i > 0)
                                            i--;
                                        if (i == 0)
                                            break;
                                    }
                                    //если заявка снята (возможно ручками) или во время клиринга
                                    if (ld.TradeList[i].OrderFromStopLimitCloseStatusOrder == cfg.Cancel)
                                    {
                                        ld.TradeList[i].StopLimitCloseStatusOrder = null;
                                        ld.TradeList[i].CloseStatusOrder = null;
                                        ld.TradeList[i].OrderFromStopLimitCloseStatusOrder = null;
                                    }
                                }
                            }
                        }

                    }
            }
            catch
            { }
        }


        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Доделать этоже для альфы при запуске проекта в продажу!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        /// <summary>
        /// Очистка листа. Если заявка на октрытие не исполнилась по заданным уловиям (отклонение цены от уровня больше заданного, время неисполнения больше заданного)
        /// </summary>
        /// <param name="ld"></param>
        private void KillOpenOrderforCondidtion(LevelItem ld)
        {
            //
            for (int i = 0; i < ld.TradeList.Count; i++)
            {
                if (ld.SettingOrderOpenClose.KillOrderOpen != cfg.Unknown && ld.TradeList[i].OpenStatusOrder != cfg.Unknown && ld.TradeList[i].OpenBalance == 0)
                {
                    if (ld.SettingOrderOpenClose.KillOrderOpen == cfg.KillofTime || ld.SettingOrderOpenClose.KillOrderOpen == cfg.KillOfTimeOrDistance)
                        if (ld.TradeList[i].OpenDate.TimeOfDay + TimeConvertor(ld.SettingOrderOpenClose.TimeWiatOpenPoz) <= DateTime.Now.TimeOfDay)
                        {
                            mainWindow.Terminals.CancelOrder(ld.TradeList[i].OpenNumberOrder, ld.Instrument, Classcode, ld.Account, ld.ClientCode);
                            ld.TradeList.Remove(ld.TradeList[i]);
                            if (i > 0)
                                i--;
                            if (i == 0)
                                break;
                        }

                    if (ld.SettingOrderOpenClose.KillOrderOpen == cfg.KillOfDictance || ld.SettingOrderOpenClose.KillOrderOpen == cfg.KillOfTimeOrDistance)
                    {
                        if (ld.Operation == cfg.Buy && ld.trendItem.HorizontalLevel + ld.Excess + ld.SettingOrderOpenClose.SpredForKillOrderOpen <= TTP_Last)
                        {
                            mainWindow.Terminals.CancelOrder(ld.TradeList[i].OpenNumberOrder, ld.Instrument, Classcode, ld.Account, ld.ClientCode);
                            ld.TradeList.Remove(ld.TradeList[i]);
                            if (i > 0)
                                i--;
                            if (i == 0)
                                break;
                        }
                        if (ld.Operation == cfg.Sell && ld.trendItem.HorizontalLevel - ld.Excess - ld.SettingOrderOpenClose.SpredForKillOrderOpen >= TTP_Last)
                        {
                            mainWindow.Terminals.CancelOrder(ld.TradeList[i].OpenNumberOrder, ld.Instrument, Classcode, ld.Account, ld.ClientCode);
                            ld.TradeList.Remove(ld.TradeList[i]);
                            if (i > 0)
                                i--;
                            if (i == 0)
                                break;
                        }

                    }
                }
            }
        }


        private TimeSpan TimeConvertor(int seconds)
        {
            int hour = seconds / 60 / 60;
            int minutes = (seconds - 60 * 60 * hour) / 60;
            int second = seconds - 60 * 60 * hour - minutes * 60;
            TimeSpan result = new TimeSpan(hour, minutes, second);

            return result;
        }
    }
}
